home *** CD-ROM | disk | FTP | other *** search
- /*
- HEADER: CUG nnn.nn;
- TITLE: LEX - A Lexical Analyser Generator
- VERSION: 1.0 for IBM-PC
- DATE: Jan 30, 1985
- DESCRIPTION: A Lexical Analyser Generator. From UNIX
- KEYWORDS: Lexical Analyser Generator YACC C PREP
- SYSTEM: IBM-PC and Compatiables
- FILENAME: YYLEX.C
- WARNINGS: This program is not for the casual user. It will
- be useful primarily to expert developers.
- CRC: N/A
- SEE-ALSO: YACC and PREP
- AUTHORS: Scott Guthery 11100 leafwood lane Austin, TX 78750
- COMPILERS: DESMET-C
- REFERENCES: UNIX Systems Manuals
- */
- /*
- * Bob Denny 28-Aug-82 Remove reference to stdio.h
- * Remove code to default lexin, change to call to
- * llstin(), generated by lex depending upon setting
- * of "-s" switch. Eliminates hardwired dependency
- * on standard I/O library. Moved declaration of
- * lexin to lexgetc().
- *
- * Bob Denny 31-Aug-82 Add call to lexswitch() in
- * the generated file, to switch to the table whose
- * name was given in the "-t" switch (or to "lextab"
- * if "-t" wasn't given). Removed hardwired setting
- * of _tabp --> "lextab" here. Now handled automagically.
- *
- * Bob Denny 21-Oct-82 Add llinit() function to re-initialize
- * yylex(), making it serially reusable.
- *
- * Initialize _tabp to NULL so lexswitch() to real table happens
- * only once.
- *
- * Bob Denny 15-Apr-83 Move NBPW to LEX.H and make it 32 on VAX native,
- * else 16.
- * Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C
- *
- * Maarten Meijer 20 Apr 1990 -- Port to THINK C on the Mac, added call
- * to yyinit() to allow reading yyparse() tables from resources
- */
-
- /*
- * yylex for lex tables
- */
- #ifdef THINK_C
- #include <stdlib.h>
- #endif
-
- #include "lex.h"
-
- #define ERROR 256 /* yacc's value */
-
- SHORTINT tst__b(register SHORTINT c, unsigned char tab[]);
- SHORTINT llinp(void);
- SHORTINT llset(void);
- void llinit(void);
- SHORTINT yylex(void);
- void llstin(void);
-
- tst__b(c, tab)
- register SHORTINT c;
- unsigned char tab[];
- {
- return(tab[(c >> 3) & 037] & (1 << (c & 07)) );
- }
-
- struct lextab *_tabp = 0;
-
- extern char *llsave[]; /* Right-context look ahead buffer */
- char *llbuf = NULL; /* work buffer */
- char *llp1 ; /*= &llbuf[0]; /* pointer to next avail.in token */
- char *llp2 ; /*= &llbuf[0]; /* pointer to end of lookahead */
- char *llend; /*= &llbuf[0]; /* pointer to end of token */
- char *llebuf; /*= &llbuf[sizeof(llbuf)]; */
- SHORTINT llbufsize = 0;
- SHORTINT lleof;
- SHORTINT yyline = 0;
-
- SHORTINT
- yylex()
- {
- register SHORTINT c, llstate;
- SHORTINT final, l, llk, i;
-
- register struct lextab *lextabp;
- unsigned char *cp;
-
- /*
- * Call llstin() to default lexin to stdin
- * and assign _tabp to "real" table.
- */
- llstin(); /* Initialize yylex() variables */
- loop:
- llk = 0;
- if (llset())
- return(0); /* Prevent EOF loop */
- llstate = 0;
- final = -1;
- lextabp = _tabp;
-
- do {
- if (lextabp->lllook && (l = lextabp->lllook[llstate]))
- {
- for (c = 0; c < NBPW; c++)
- if (l&(1<<c))
- llsave[c] = llp1;
- llk++;
- }
- if ((i = lextabp->llfinal[llstate]) != -1)
- {
- final = i;
- llend = llp1;
- }
- if ((c = llinp()) < 0)
- break;
-
- if ((cp = lextabp->llbrk) && llk==0 && tst__b(c, cp)) /* break char */
- {
- llp1--;
- break;
- }
- } while ((llstate = (*lextabp->llmove)(lextabp, c, llstate)) != -1);
-
-
- if (llp2 < llp1)
- llp2 = llp1;
- if (final == -1)
- {
- llend = llp1;
- if (llstate == 0 && c < 0)
- return(0);
- if ((cp = lextabp->llill) && tst__b(c, cp))
- {
- lexerror("Illegal character: %c (%d)", c, c);
- goto loop;
- }
- return(ERROR);
- }
- if (c = (final >> 11) & 037)
- llend = llsave[c-1];
- if ((c = (*lextabp->llactr)(final & 03777)) >= 0)
- return(c);
- goto loop;
- }
-
- SHORTINT
- llinp()
- {
-
- register c;
- register struct lextab *lextabp;
- register unsigned char *cp;
-
- lextabp = _tabp;
- cp = lextabp->llign; /* Ignore class */
- for (;;)
- {
- /*
- * Get the next character from the save buffer (if possible)
- * If the save buffer's empty, then return EOF or the next
- * input character. Ignore the character if it's in the
- * ignore class.
- */
- c = (llp1 < llp2) ? *llp1 & 0377 : (lleof) ? EOF : lexgetc();
- if(c == '\n')
- yyline++; /* added 90/06/03 MM */
- if (c >= 0)
- { /* Got a character? */
- if (cp && tst__b(c, cp))
- continue; /* Ignore it */
- if (llp1 >= llebuf)
- { /* No, is there room? */
- lexerror("Token buffer overflow");
- exit(1);
- }
- *llp1 = c; /* Store in token buff */
- llp1++;
- }
- else
- lleof = 1; /* Set EOF signal */
- return(c);
- }
- }
-
- SHORTINT
- llset()
- /*
- * Return TRUE if EOF and nothing was moved in the look-ahead buffer
- */
-
- {
- register char *lp1, *lp2;
-
- for (lp1 = llbuf, lp2 = llend; lp2 < llp2;) {
- *lp1 = *lp2++;
- lp1++;
- }
- llend = llp1 = llbuf;
- llp2 = lp1;
- return(lleof && lp1 == llbuf);
- }
-
- /*
- * Re-initialize yylex() so that it can be re-used on
- * another file.
- */
- void
- llinit()
- {
- extern void yyinit(void);
- llp1 = llp2 = llend = &llbuf[0];
- llebuf = llbuf + llbufsize;
- lleof = yyline = 0;
- yyinit(); /* to check for resources */
- }
-